/*! \file manifest_array.h
	\author HiddenSeeker

	Describes a manifest_array
*/
#include "../abstractnode.h"
#include "list.h"
#pragma once

typedef ListNode<AbstractNode> Compound;

class MethodSelectDelegate;
class ParentData;
class JBFile;

/*!  \class ManifestArray
	 Describes an array, defines by his elements
*/
class ManifestArray: public AbstractNode
{
 private:
		 Compound * m_compound;
		 /**
		   Creates a delegates for creation all data
		  */
		 std::vector< std::vector<MethodSelectDelegate *> > m_delegates; 
		 /**
		   Finds a type, used by data
		  */
		 std::string m_type;
		 /**
		   Returns a types, used by arguments
		  */
		 std::vector<std::string> m_arg_types;
		 /**
		    Attributed local var
		  */
		 int m_local_var;
		 /**
		     A vector of argument types
		  */
		 void getArgumentTypes(ParentData * data);
		 /** Tests, whether somebody returned type
		  */
		 bool hasType(const std::string & type);
		 AbstractNode * getNodeWithType(const std::string & type);
	
		 void createArray(ParentData * data);

		 void createDelegates(ParentData * data);


		 //Data used for code generation
		 unsigned short m_array_class;  // A class,used by new
		 unsigned short m_array_constructor; // A method ref on constructor
		 unsigned short m_array_make;        // An array make method ref
		 unsigned short m_array_put;         // An array put method ref

		 unsigned short m_integer_class;     // An integer class
		 unsigned short m_int_constructor;   // An integer constructor 
		 unsigned short m_size_ref;          // An array size integer ref
		 std::vector<unsigned short> m_nums_ref;  // A numbers method refs

		 void createInteger(JBFile * file, unsigned short ref);
		 void createArray(JBFile * file);
		 /*! Puts an object to array
			 \param[in] file file
			 \param[in[ pos  position
		  */
		 void putObject(JBFile * file, unsigned int pos,ParentData * data);
 public:
		 inline ManifestArray(const YYLTYPE & pos, Compound * c): AbstractNode(pos)
		 {
			 m_compound=c;
		 }
		 /*! Checks common errors
		  */
		 virtual void checkCommonErrors(ParentData * data);
		 /*! Returns unknown type
		 */
		 virtual std::string getType(ParentData * data);

		 /*! Fills a constant table for method
		  */
		 virtual void fillConstant(ParentData * data);
		 /*! Produces a code for array
			 \param[in] data used data
		  */
		 virtual void produceCode(ParentData * data);
		 void write(GraphStream * s);
		 
	     ~ManifestArray();
};



